package com.coder4j.starter.tools.util;

import lombok.Data;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * @author Keller
 * @date 2022-01-13 17:27:31
 * 错误工具类
 */
public class ExceptionUtil {

    /**
     * 获取错误堆栈信息
     * @param t
     * @return
     */
    public static String getStackTrace(Throwable t) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        try {
            t.printStackTrace(pw);
            return sw.toString();
        } finally {
            pw.close();
        }
    }

    /**
     * 获取错误堆栈信息
     * @param t
     * @param clazz
     * @return
     */
    public static StackTraceInfo getStackTraceInfo(Throwable t,Class clazz){
        return getStackTraceInfo(t,clazz.getCanonicalName());
    }

    public static StackTraceInfo getStackTraceInfo(Throwable t,String filter){
        String fullStackTrace = getStackTrace(t);
        StackTraceInfo info = new StackTraceInfo();
        info.setFilterStr(filter);
        info.setExceptionType(t.getClass().getCanonicalName());
        if(StringUtils.isEmpty(fullStackTrace)){
            return info;
        }

        //全部堆栈
        info.setFullStackTrace(fullStackTrace);

        String[] array = fullStackTrace.split("\n");
        StringBuilder builder = new StringBuilder();

        if(array.length == 0){
            return info;
        }
        //第一行有简要的错误描述，不过滤
        builder.append(array[0]).append("\n");

        //过滤出和指定类相关的堆栈
        for (String str : array) {
            if(str.contains(info.getFilterStr())){
                builder.append(str).append("\n");
            }
        }

        //过滤后的堆栈
        if(builder.length() > 0){
            info.setFilterStackTrace(builder.toString());
        }
        return info;
    }

    @Data
    public static class StackTraceInfo {
        /**
         * 过滤字符串
         */
        String filterStr;
        /**
         * 错误类型
         */
        String exceptionType;
        /**
         * 过滤后的异常堆栈
         */
        String filterStackTrace;
        /**
         * 全量的异常堆栈
         */
        String fullStackTrace;
    }
}
